<?php
/**
 * Абстрактный класс на котором будут основыватся елементы формы редактирования записи в таблице
 * @author Demianchuk Dmitro
 * @email d.demianchuk@gmail.com
 * @date 24.12.11
 * @version 1.0
 * @package adminArea.components.ATableEditor
 */
abstract class EditorComponent extends CBaseController
{
	/**
	 * @var string - имя столбца в таблеце базы данных
	 */
	protected $name;

	/**
	 * @var int - id строки в таблице, если 0 то создать новую запись
	 */
	protected $itemId;

	/**
	 * @var string - название отношения по которому связана таблица
	 */
	protected $relationName = null;

	/**
	 * @var string - название поля в таблице по которому идет связь
	 */
	protected $relationField = null;

	/**
	 * @var CActiveRecord - запись в таблице, которя редактируеться
	 */
	protected $current = null;

	/**
	 * @var CActiveRecord - модель
	 */
	protected $model;

	/**
	 * @var boolean $allowNull - принимает ли поле значение NULL
	 */
	protected $allowNull = false;

	/**
	 * @abstract
	 * Возвращает элемент в виде html строки
	 */
	abstract public function show();

	/**
	 * Сохраняет значение переданое через $_POST
	 * @abstract
	 * @param CActiveRecord $model
	 * @return CActiveRecord
	 */
	abstract public function save($model);

	/**
	 * Метод определяет являеться ли значение текущей ячейки NULL
	 * @abstract
	 * @return boolean
	 */
	abstract public function isNull();

	/**
	 * Определяет можно ли записать в текущую ячейку значение NULL
	 * @return boolean
	 */
	public function allowNull(){
		if($this->allowNull===true){
			if(isset($this->model->tableSchema->columns[$this->name])){
				return $this->model->tableSchema->columns[$this->name]->allowNull;
			}else{
				return true;
			}
		}else{
			return false;
		}
	}

	/**
	 * Возвращает имя ячейки
	 * @return string
	 */
	public function getName(){
		return $this->name;
	}

	/**
	 * Возвращает подпись к ячейке
	 * @return string
	 */
	public function getLabel(){
		$labels =  $this->model->attributeLabels();
		if(isset($labels[$this->name])){
			return $labels[$this->name];
		}else{
			return $this->name;
		}
	}

	/**
	 * @param array $params - параметры для инициализации обьекта
	 * @param CActiveRecord $model - модедь
	 * @param int $itemId - id редактируемого элемента, 0 если элемент нужно добавить
	 */
	public function __construct($params,$model,$itemId=0){
		$this->model = $model;
		foreach($params AS $k=>$v){
			if(property_exists(get_class($this),$k)){
				$this->$k = $v;
			}
		}
		$this->itemId = $itemId;
		if($this->itemId!=0){
			$this->current = $this->model->findByPk($this->itemId);
		}
	}

	/**
	 * Возвращает строку значение в зависимости находиться она в таблице текстов или нет
	 * @param string $relationName - имя отношения по которому связаны таблици
	 * @param string $relationField - имя поля в свзянной таблице
	 * @param CActiveRecord $item - запись в таблице
	 * @return string
	 */
	protected function getData($item,$relationName=null,$relationField=null){
		$value = '';
		if($relationName!==null){
			if($relationField===null){
				$relationField = $this->relationField;
			}
			if(is_object($item->$relationName)){
				$value = $item->$relationName->$relationField;
			}
			if(isset($item->$relationName) && gettype($item->$relationName)==='string'){
				$value = $item->$relationName;
			}
		}else{
			if($relationField===null){
				$relationField = $this->name;
			}
			$value = $item->$relationField;
			if(is_object($value)){
				$value = $value->string;
			}
		}
		return $value;
	}

	public function getViewFile($viewFile){
		$className = get_class($this);
		$class = new ReflectionClass($className);
		return dirname($class->getFileName()).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$viewFile.'.php';
	}

	public function render($view,$data=null,$return=false)
	{
		if(($viewFile=$this->getViewFile($view))!==false)
			return $this->renderFile($viewFile,$data,$return);
		else
			throw new CException(Yii::t('yii','{widget} cannot find the view "{view}".',
				array('{widget}'=>get_class($this), '{view}'=>$view)));
	}
}
